• Nenhum resultado encontrado

Constrângeri în confruntarea ş abloanelor

8.2. Un exemplu de sortare

Constrângeri în confruntarea şabloanelor 117

(not (arie ?a1 $?)) =>

(assert (arie ?a1 ?i)) )

(defrule selectie4-inlocuieste-in-grupa

; initializeaza o grupa cu un obiect daca are aria corespunzatoare

; grupei si daca e mai gros decit oricare dintre cele existente deja ; in grupa

(lego (id ?i) (arie ?a1) (grosime ?g1)) ?a <- (arie ?a1 $?list)

(lego (id ?j) (grosime ?g2&:(> ?g1 ?g2))) (test (member$ ?j $?list))

=>

(retract ?a)

(assert (arie ?a1 ?i)) )

(defrule selectie4-includ-in-grupa

; include un obiect in grupa corespunzatoare

; daca e la fel de gros decit oricare dintre cele existente deja

(lego (id ?i) (arie ?a1) (grosime ?g1)) ?a <- (arie ?a1 $?list)

(test (not (member$ ?i $?list))) (lego (id ?j) (grosime ?g1)) (test (member$ ?j $?list)) =>

(retract ?a)

(assert (arie ?a1 $?list ?i)) )

Programarea bazată pe reguli 118

AplicaŃia începe prin definiŃia cadrelor de fapte care vor memora numele profesorilor şi datele ce se cunosc despre ei. Aceste date vor fi folosite pentru aplicarea criteriilor de acordare a gradaŃiilor de merit. Exemplul nostru foloseşte patru profesori – ai căror parametri sunt memoraŃi imediat după definiŃiile de template:

(deftemplate persoana (slot nume)

(slot sex) (slot varsta) (slot vechime) (slot grad) (slot nr-ore)

(multislot olimpiade) (slot publicatii) )

(deffacts personal

(persoana (nume Ionescu)(sex b)(varsta 30)(vechime 5)(grad 2)(nr-ore 18)(olimpiade 1999 3 1998 5 1997

2)(publicatii 2))

(persoana (nume Popescu)(sex f)(varsta 35)(vechime 10)(grad 1)(nr-ore 17)(olimpiade 1999 4 1998 5 1997

3)(publicatii 1))

(persoana (nume Georgescu)(sex f)(varsta 32)(vechime 7)(grad 2)(nr-ore 18)(olimpiade 1999 5 1998 6 1997

1)(publicatii 0))

(persoana (nume Isopescu)(sex f)(varsta 40)(vechime 25)(grad 0)(nr-ore 20)(olimpiade 1999 1 1998 1 1997

1)(publicatii 0)) )

Se defineşte template-ul faptelor care vor înregistra punctajele persoanelor.

Apoi aceste fapte sunt iniŃializate la valorile 0 ale punctajului:

(deftemplate punctaj (slot nume)

(slot valoare) )

(deffacts puncte

(punctaj (nume Ionescu)(valoare 0)) (punctaj (nume Popescu)(valoare 0)) (punctaj (nume Georgescu)(valoare 0)) (punctaj (nume Isopescu)(valoare 0)) )

Constrângeri în confruntarea şabloanelor 119

Primele reguli calculează punctajele corespunzătoare activităŃilor profesorilor. Regula criteriu-grad aplică criteriul grad didactic. La fiecare aplicare a acestei reguli într-un fapt punctaj al unei persoane se modifică câmpul valoare prin adăugarea unui număr de puncte corespunzător gradului didactic – indicat prin comentarii în antetul regulii. Pentru prima dată în această regulă avem un exemplu de folosire a comenzii if:

(defrule criteriu-grad

; doctor = 50 puncte

; grad 1 = 30 puncte

; grad 2 = 20 puncte

; definitivat = 10 puncte

; grad 0 = 0 puncte

?per <- (persoana (nume ?num) (grad ?grd&~folosit)) ?pct <- (punctaj (nume ?num) (valoare ?val))

=>

(modify ?per (grad folosit))

(if (eq ?grd doctor) then (modify ?pct (valoare =(+

?val 50)))

else (if (eq ?grd 1) then (modify ?pct (valoare =(+

?val 30)))

else (if (eq ?grd 2) then (modify ?pct (valoare =(+

?val 20)))

else (if (eq ?grd definitivat) then (modify ?pct (valoare =(+ ?val 10)))))))

)

Regula criteriu-olimpiade se aplică de un număr de ori egal cu numărul de profesori multiplicat cu numărul de olimpiade în care aceştia au avut elevi:

(defrule criteriu-olimpiade

; fiecare elev la olimpiada in ultimii 3 ani aduce 5

; puncte

?per <- (persoana (nume ?num)

(olimpiade ?an ?elevi $?rest)) ?pct <- (punctaj (nume ?num) (valoare ?val)) =>

(modify ?per (olimpiade $?rest))

(modify ?pct (valoare =(+ ?val (* 5 ?elevi)))) )

Programarea bazată pe reguli 120

Regula criteriu-vechime se aplică câte o dată pentru fiecare persoană.

Conform criteriului de vechime, la fiecare aplicare valoarea punctajului persoanei este incrementată cu un număr egal cu numărul anilor de vechime:

(defrule criteriu-vechime

; fiecare an de vechime aduce 1 punct

?per <- (persoana (nume ?num) (vechime ?ani&~folosit)) ?pct <- (punctaj (nume ?num) (valoare ?val))

=>

(modify ?per (vechime folosit))

(modify ?pct (valoare =(+ ?val (* 1 ?ani)))) )

Regula criteriu-publicatii se aplică din nou câte o dată pentru fiecare persoană. Conform criteriului publicaŃiilor, la fiecare aplicare valoarea punctajului persoanei este incrementată cu de două ori numărul publicaŃiilor acesteia:

(defrule criteriu-publicatii

; fiecare publicatie aduce 2 puncte ?per <- (persoana (nume ?num)

(publicatii ?publ&~folosit)) ?pct <- (punctaj (nume ?num) (valoare ?val)) =>

(modify ?per (publicatii folosit))

(modify ?pct (valoare =(+ ?val (* 2 ?publ)))) )

Şi regula criteriu-nr-ore are un număr de aplicaŃii egal cu numărul persoanelor. La fiecare aplicare valoarea punctajului persoanei este incrementată cu jumătate din numărul orelor prestate de aceasta săptămânal:

(defrule criteriu-nr-ore

; fiecare ora pe saptamina aduce 0.5 puncte

?per <- (persoana (nume ?num) (nr-ore ?ore&~folosit)) ?pct <- (punctaj (nume ?num) (valoare ?val))

=>

(modify ?per (nr-ore folosit))

(modify ?pct (valoare =(+ ?val (* 0.5 ?ore)))) )

Urmează trei reguli de sortare. PriorităŃile acestor trei reguli sunt, toate, -100, deci mai mici decât ale regulilor de aplicare a criteriilor, date mai sus. Ca urmare, aceste trei reguli se vor aplica numai în cazul în care nici o regulă din cele de mai

Constrângeri în confruntarea şabloanelor 121

sus nu mai poate fi aplicată. Acest lucru se întâmplă numai când toate câmpurile faptelor persoană sunt folosite deja. Cititorul a observat, cu siguranŃă, că am marcat faptul că s-a lucrat asupra unui câmp al unui fapt persoana, prin înregistrarea valorii folosit în acest câmp.

Regula sortare-initializare se aplică o singură dată, la începutul sortării persoanelor, şi ea va introduce un fapt lista-finală – iniŃial vid. O pereche, formată dintr-un nume de profesor ales la întâmplare şi valoarea punctajului său, va intra apoi în această listă. Faptul punctaj corespunzător este retras pentru a nu mai fi luat încă o dată în considerare:

(defrule sortare-initializare

; initializeaza lista finala in care persoanele vor fi

; asezate in ordinea descrescatoare a punctajelor (declare (salience -100))

(not (lista-finala $?))

?pct <- (punctaj (nume ?num) (valoare ?val)) =>

(assert (lista-finala ?num ?val)) (retract ?pct)

)

Vom sorta lista-finală în ordinea descrescătoare a punctajelor calculate. Regula sortare-extrema-stinga tratează cazul în care o valoare de punctaj a unui profesor este mai mare decât cea mai mare valoare înscrisă în listă, adică cea din extrema stângă a listei. Perechea formată din numele persoanei şi valoarea punctajului său este inclusă acolo:

(defrule sortare-extrema-stinga

; plaseaza o persoana in capul listei (declare (salience -100))

?lst <- (lista-finala ?prim-nume ?prim-val $?ultime) ?pct <- (punctaj (nume ?num)

(valoare ?val&:(> ?val ?prim-val))) =>

(assert (lista-finala ?num ?val

?prim-nume ?prim-val $?ultime)) (retract ?lst ?pct)

)

Regula sortare-extrema-dreapta tratează cazul în care o valoare de punctaj a unui profesor este mai mică decât cea mai mică valoare înscrisă în listă, adică cea din extrema dreaptă:

(defrule sortare-extrema-dreapta

Programarea bazată pe reguli 122

; plaseaza o persoana in coada listei (declare (salience -100))

?lst <- (lista-finala $?prime ?ultim-nume ?ultim-val) ?pct <- (punctaj (nume ?num)

(valoare ?val&:(< ?val ?ultim-val))) =>

(assert (lista-finala $?prime ?ultim-nume ?ultim-val ?num ?val))

(retract ?lst ?pct) )

Ultimul caz tratat este cel al unei valori care trebuie plasată între două valori aflate în listă:

(defrule sortare-mijloc

; plaseaza o persoana intre alte doua persoane in lista (declare (salience -100))

?lst <- (lista-finala $?prime ?un-nume

?o-val&:(numberp ?o-val) ?alt-nume

?alt-val $?ultime) ?pct <- (punctaj

(nume ?num)

(valoare ?val&:(and (< ?val ?o-val)

(> ?val ?alt-val)))) =>

(assert (lista-finala $?prime

?un-nume ?o-val ?num ?val

?alt-nume ?alt-val $?ultime))

(retract ?lst ?pct) )

Capitolul 9