;;;-------------------------------------------------------------------------- ;;; Fuzzy Econo-Dynamics - N Firme, Comp/Max-Strategy - v3 ;;;-------------------------------------------------------------------------- ;;; ;;; Implementeaza un sistem economic format din doua sau mai multe ;;; firme concurente ce isi modifica pretul de vanzare al produsului ;;; functie de beneficiu si pretul concurentei (Strategia Comp) sau ;;; numai in functie de pretul concurentei (Strategia Max). ;;;__________________________________________________________________________ ;;; ;;; Beneficiul depinde neliniar de pret: la pret prea scazut, acesta ;;; scade (diferenta pret-cheltuieli mica sau negativa). De asemenea, la ;;; pret prea mare, beneficiul scade - in primul rand daca concurenta are ;;; un pret mai mic, dar chiar si la preturi egale, dar mari, deoarece sunt ;;; mai putini cumparatori pe piata. ;;; ;;; Dinamica apare deoarece modificarea pretului (care este reactia ;;; firmei, politica firmei fata de beneficiul avut la momentul respectiv) ;;; este lenta (cu intarziere). De asemenea, concurenta raspunde cu intarziere ;;; la reactia firmei. ;;;__________________________________________________________________________ ;;; ;;; Fisierul cu datele de intrare "Ec_dyn.in" trebuie sa contina pentru ;;; toate cele N firme numele acestora, pretul initial al produsului, precum ;;; si strategia pe care aceasta o foloseste. Pentru strategie se pot folosi ;;; simbolurile 'comp' si 'max' (implicit se foloseste 'comp'). Dupa introducerea ;;; acestor date se va specifica si matricea M cu intarzierile reactiilor firmelor. ;;; Programul creaza fisierul "Ec_dyn.out" cu datele de iesire, preturile ;;; si profiturile celor N firme, pentru prelucrari statistice ulterioare. ;* V9->V10 Optiune suplimentara de fluctuatie a pretului (valoarea poate ramane aceiasi), ;* optiune absolut necesara pentru stabilitatea sistemului (in absenta acesteia ;* sistemul economic nu poate atinge niciodata un punct de echilibru) ;* V10->V11 Sunt introduse mai multe firme pe piata (nu doar doua ca in modelul initial) ;* Intarzierile cu care o firma afla preturile celorlalte firme sunt citite ;* dintr-un fisier text sub forma unei matrici ;* V11->NV1 Fluctuatia pretului nu mai este realizata doar cu prag fix (variabil in ;* variante anterioare), ci poate fi calculata si fuzzy. Tipul de increment este ;* acelasi pentru toate firmele de pe piata ;* NV2 - s-a adaugat o noua strategie max-benefit (de maximizare a profitului) ;* NV3 - posibilitatea asocierii pentru fiecare firma a unui tip de increment (fuzzy/fix) ;* - introducerea datelor despre o firma in fisierul "Ec_dyn.in" va respecta formatul ;* nume_firma pret_initial strategie(max/comp) tip_incr(fix/fuzzy) val_incr (daca este fix) ;* Implicit: - tip increment = fuzzy; valoare implicita increment fix = 0.1 ;* - tip strategie = comp ;============================================================================ ; CONSTRUCTII GENERALE ;============================================================================ (defmethod + (?a) (return ?a) ) (deftemplate pret ; preturile au aceeasi structura pentru ambele firme 1. 25. USD ((scazut ( 3 1) (10 0)) (mediu ( 5 0) (8 1) (21 0)) ; suprapunere ne-perfecta cu urmatoarea f.a. (ridicat (10 0) (25 1))) ) (deftemplate beneficiu ; firmele considerate de acceeasi pondere, ; deci beneficiile cu aceeasi structura -25. 65. USD ((foarte_scazut (-25 1) (25 0)) (scazut (15 0) (25 1) (35 0)) (mediu (25 0) (43 1) (45 0)) (ridicat (35 0) (55 1) (60 0)) (foarte_ridicat (45 0) (65 1))) ) ;(deftemplate pret ; preturile au aceeasi structura pentru ambele firme ; 1. 25. USD ; ((scazut ( 5 1) (10 0)) ; (mediu ( 5 0) (10 1) (15 0)) ; (ridicat (10 0) (15 1))) ;) ;(deftemplate beneficiu ; firmele considerate de acceeasi pondere, ; ; deci beneficiile cu aceeasi structura ; -25. 65. USD ; ((foarte_scazut (-25 1) (25 0)) ; (scazut (15 0) (25 1) (35 0)) ; (mediu (25 0) (35 1) (45 0)) ; (ridicat (35 0) (45 1) (55 0)) ; (foarte_ridicat (45 0) (65 1))) ;) (deftemplate informatii (slot id) (slot pret (type FUZZY-VALUE pret)) ) (defglobal ?*step* = 0 ; variabila ce contorizeaza numarul de pasi ?*nfc* = 1 ; numarul de firme concurente ) ; (valoarea sa e determinata dupa citire fisier "Ec.dyn.in") ;============================================================================ ; ; REGULI FUZZY DE CALCUL BENEFICIU ; ;============================================================================ (defrule beneficiu_pret_firma_scazut_pret_concurenta_scazut (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret scazut)) ; firma #1 are pret scazut (informatii (id ?f2) (pret scazut)) ; firma #2 are pret scazut => (assert (beneficiu mediu)) ) (defrule beneficiu_pret_firma_scazut_pret_concurenta_mediu (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret scazut)) (informatii (id ?f2) (pret mediu)) => (assert (beneficiu more-or-less mediu)) ) (defrule beneficiu_pret_firma_scazut_pret_concurenta_ridicat (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret scazut)) (informatii (id ?f2) (pret ridicat)) => (assert (beneficiu foarte_ridicat)) ) (defrule beneficiu_pret_firma_mediu_pret_concurenta_scazut (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret mediu)) (informatii (id ?f2) (pret scazut)) => (assert (beneficiu scazut)) ) (defrule beneficiu_pret_firma_mediu_pret_concurenta_mediu (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret mediu)) (informatii (id ?f2) (pret mediu)) => (assert (beneficiu ridicat)) ) (defrule beneficiu_pret_firma_mediu_pret_concurenta_ridicat (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret mediu)) (informatii (id ?f2) (pret ridicat)) => (assert (beneficiu somewhat ridicat)) ) (defrule beneficiu_pret_firma_ridicat_pret_concurenta_scazut (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret ridicat)) (informatii (id ?f2) (pret scazut)) => (assert (beneficiu foarte_scazut)) ) (defrule beneficiu_pret_firma_ridicat_pret_concurenta_mediu (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret ridicat)) (informatii (id ?f2) (pret mediu)) => (assert (beneficiu scazut)) ) (defrule beneficiu_pret_firma_ridicat_pret_concurenta_ridicat (calcul_beneficiu ? ?f1 ?f2) (informatii (id ?f1) (pret ridicat)) (informatii (id ?f2) (pret ridicat)) => (assert (beneficiu scazut)) ) ;============================================================================ ; ; REGULI FUZIFICARE / DEFUZIFICARE ; ;============================================================================ ; Regulile de calcul al beneficiului la un pret actual si la pret intarziat ; se vor activa de n*(n-1) ori deorece variabila ?id1 va fi inlocuita pe rand ; cu unul din simbolurile din lista numelor firmelor, iar variabila ?id2 va ; fi una din firmele concurente (defrule startare_calcul_beneficiu_la_pret_actual (declare (salience -2)) (not (valoare_pret ? scade|creste|aceiasi)) ; daca modificarea preturilor s-a efectuat (lista_firme $? ?id1 $?) ; se selecteaza firma curenta ?id1 (lista_firme $? ?id2 &~?id1 $?) ; si una din firmele concurente ?id2 (lista_preturi ?id1 ?vpaf $?) ; pretul actual al firmei ?vpaf (lista_preturi ?id2 $?l ?vpic $?) ; pretul intarziat al concurentei ?vpic (strategie ?id1 ?str) (intarziere ?id1 ?id2 ?tau) (test (eq (length$ $?l) ?tau)) => (assert (calcul_beneficiu pret_actual ?id1 ?id2) (informatii (id ?id1) (pret (PI 0 ?vpaf))) (informatii (id ?id2) (pret (PI 0 ?vpic))) ) (if (neq ?str max-profit) then (assert (adauga_pret_concurenta ?id1 ?vpic)) ) ) (defrule startare_calcul_beneficiu_la_pret_intarziat (declare (salience -2)) (not (valoare_pret ? scade|creste|aceiasi)) ; daca modificarea preturilor s-a efectuat (lista_firme $? ?id1 $?) ; se selecteaza firma curenta ?id1 (lista_firme $? ?id2 &~?id1 $?) ; si una din firmele concurente ?id2 (lista_preturi ?id1 $?l ?vpif $?) ; pretul intarziat al firmei ?vpif (lista_preturi ?id2 ?vpac $?) ; pretul actual al concurentei ?vpac (or (and (strategie ?id2 max-profit) (tip-increment ?id2 fuzzy)) (strategie ?id2 comp-profit) ) (intarziere ?id2 ?id1 ?tau) (test (eq (length$ $?l) ?tau)) => (assert (calcul_beneficiu pret_intarziat ?id1 ?id2) (informatii (id ?id1) (pret (PI 0 ?vpif))) (informatii (id ?id2) (pret (PI 0 ?vpac))) ) ) (defrule startare_evaluare_beneficiu_pret_mai_ridicat (declare (salience -2)) (or (evaluare_beneficiu ?id1) (strategie ?id1 max-profit)) (not (valoare_pret ? scade|creste|aceiasi)) (lista_preturi ?id1 ?vp1 $?) (lista_preturi ?id2 &~?id1 $?l ?vp2 $?) (intarziere ?id1 ?id2 ?tau) (test (and (eq (length$ $?l) ?tau) (< ?vp1 (get-u-to pret)) )) (or (and (valoare_increment ?id1 ?incr) (tip-increment ?id1 fuzzy)) (tip-increment ?id1 fix ?incr) ) => (if (< (+ ?vp1 ?incr) (get-u-to pret)) then (assert (informatii (id ?id1) (pret (PI 0 (+ ?vp1 ?incr))))) else (assert (informatii (id ?id1) (pret (PI 0 (get-u-to pret))))) ) (assert (informatii (id ?id2) (pret (PI 0 ?vp2))) (calcul_beneficiu pret_mai_ridicat ?id1 ?id2) ) ) (defrule startare_evaluare_beneficiu_pret_mai_scazut (declare (salience -2)) (or (evaluare_beneficiu ?id1) (strategie ?id1 max-profit)) (not (valoare_pret ? scade|creste|aceiasi)) (lista_preturi ?id1 ?vp1 $?) (lista_preturi ?id2 &~?id1 $?l ?vp2 $?) (intarziere ?id1 ?id2 ?tau) (test (and (eq (length$ $?l) ?tau) (> ?vp1 (get-u-from pret)) )) (or (and (valoare_increment ?id1 ?incr) (tip-increment ?id1 fuzzy)) (tip-increment ?id1 fix ?incr) ) => (if (> (- ?vp1 ?incr) (get-u-from pret)) then (assert (informatii (id ?id1) (pret (PI 0 (- ?vp1 ?incr))))) else (assert (informatii (id ?id1) (pret (PI 0 (get-u-from pret))))) ) (assert (informatii (id ?id2) (pret (PI 0 ?vp2))) (calcul_beneficiu pret_mai_scazut ?id1 ?id2) ) ) ; Defuzificarea poate fi realizata prin doua metode COG si MAXIMUM ; functie de functia utilizata moment-defuzzify sau maximum-defuzzify (defrule calcul_valori_crisp_beneficiu (declare (salience -1)) ?d <- (calcul_beneficiu ?tip ?id1 ?id2) ; ?d = adresa fapt decizie ?b <- (beneficiu ?) ; ?b = adresa fapt beneficiu ?i1 <- (informatii (id ?id1)) ; se sterg informatiile ce au servit la ?i2 <- (informatii (id ?id2)) ; calcularea beneficiului => (retract ?d ?b ?i1 ?i2) (assert (valoare_beneficiu ?tip ?id1 ?id2 (moment-defuzzify ?b))) ; (assert (valoare_beneficiu ?tip ?id1 ?id2 (maximum-defuzzify ?b))) ) ;============================================================================ ; ; REGULI CITIRE / SCRIERE IN FISIER ; REGULA DE INITIALIZARE LISTE DE PRETURI ; ;============================================================================ (defrule open_file ; result file (declare (salience 20)) ; max salience 20 => (open "Ec_dyn.in" in "r") (bind ?lista (create$ )) (bind ?error 0) (bind ?nr_firme 0) (while (neq (bind ?line (readline in)) EOF) do (bind ?line (explode$ ?line)) (if (> (length$ ?line) 0) then (if (eq ?nr_firme 0) then ; nu s-au citit toate firmele (bind ?nume_firma (nth$ 1 ?line)) (bind ?pret_initial (nth$ 2 ?line)) (bind ?strategy (nth$ 3 ?line)) (bind ?tip_incr(nth$ 4 ?line)) (if (not (numberp ?nume_firma)) then (if (or (not (symbolp ?tip_incr)) (neq (lowcase ?tip_incr) fix)) then (assert (tip-increment ?nume_firma fuzzy)) ; tip implicit increment = fuzzy else (bind ?val_incr (nth$ 5 ?line)) (if (not (numberp ?val_incr)) then ; valoare implicita increment fix = 0.1 (assert (tip-increment ?nume_firma ?tip_incr 0.1)) else (assert (tip-increment ?nume_firma ?tip_incr ?val_incr)) ) ) (if (or (not (symbolp ?strategy)) (neq (lowcase ?strategy) comp max)) then (bind ?strategy comp) ) ; tip implicit strategie (if (numberp ?pret_initial) then (bind ?lista (create$ ?lista ?nume_firma)) (assert (strategie ?nume_firma (sym-cat (lowcase ?strategy) -profit)) (pret_initial ?nume_firma ?pret_initial)) else (bind ?error 1) (break) ) else (bind ?nr_firme (length$ ?lista)) (bind ?firma_curenta 1) (if (< ?nr_firme 2) then (bind ?error 2) (break) ) ) ) (if (neq ?nr_firme 0) then (loop-for-count (?i 1 ?nr_firme) do (if (numberp (bind ?v (nth$ ?i ?line))) then (if (neq ?firma_curenta ?i) then (assert (intarziere (nth$ ?firma_curenta ?lista) (nth$ ?i ?lista) ?v)) else (assert (preturi_concurenta (nth$ ?firma_curenta ?lista))) ) else (bind ?error 3) (break) ) ) (if (neq ?error 3) then (bind ?firma_curenta (+ ?firma_curenta 1)) else (break) ) ) ) ) (printout t "Fisierul de intrare \"Ec_dyn.in\" ") (switch ?error (case 1 then (printout t "are preturile initiale eronate." t)) (case 2 then (printout t "are un numarul de firme prea mic." t)) (case 3 then (printout t "are intarzierile reactiilor firmelor incorecte." t)) (default (printout t "a fost citit cu succes." t) (assert (lista_firme ?lista)) (bind ?*nfc* (- ?nr_firme 1)) ) ) (close in) (open "Ec_dyn.out" d "w") (printout t crlf "Datele de iesire se afla in fisierul \"Ec_dyn.out\"" t t) ; (format d " Pret vs Beneficiu %n %n") ; (format d " P1 vs B1 || P2 vs B2 %n %n") ; (printout t "Introduceti numarul maxim de pasi de calcul(implicit " ?*step* "): " t) ; (bind ?n (read)) ; (if (numberp ?n) then (bind ?*step* (abs (integer ?n))) ) ) (defrule completare_valori_lista_preturi (declare (salience 10)) (lista_firme $? ?firma $?) (intarziere ? ?firma ?v) (not (exists (intarziere ? ?firma ?v2 &:(> ?v2 ?v)) )) ?f <- (pret_initial ?firma ?vp) => (retract ?f) (bind $?lista (create$ ?vp)) (loop-for-count (?i 1 ?v) do (bind $?lista (create$ $?lista ?vp)) ) (assert (lista_preturi ?firma $?lista)) ) (defrule afisare_informatii_1 (declare (salience -10)) (lista_firme ?id $?last) (lista_preturi ?id ?vpf $?) ; vpf - valoare curenta pret firma ?f <- (beneficiu_mediu pret_actual ?id ?vbf) => (retract ?f) (format d "%3d %4.2f %6.3f" ?*step* ?vpf ?vbf) ; (format t "%3d %3.1f -- %6.3f" ?*step* ?vpf ?vbf) (bind ?*step* (+ ?*step* 1)) (assert (lista_firme_de_afisat $?last)) ) (defrule afisare_informatii_2 ?f1 <- (lista_firme_de_afisat ?id $?last) (lista_preturi ?id ?vpf $?) ; vpf - valoare curenta pret firma ?f2 <- (beneficiu_mediu pret_actual ?id ?vbf) => (retract ?f1 ?f2) (format d " %4.2f %6.3f" ?vpf ?vbf) (if (neq (length$ $?last) 0) then (assert (lista_firme_de_afisat $?last)) ; (printout t " |") else ; (printout t t) (format d " %n")) ) (defrule close_file_1 (declare (salience -20)) => (close d) ) (defrule close_file_2 (declare (salience 20)) (lista_preturi ?id $?) ?f <- (lista_firme $? ?id $?) (test (>= ?*step* 100)) ; dupa 200 de pasi se opreste automat => (retract ?f) ) ;============================================================================ ; ; REGULI PENTRU CALCULUL BENEFICIULUI MEDIU ; SI A MEDIEI PRETURILOR CONCURENTEI ; ;============================================================================ ; Se goleste lista preturilor practicate de concurenta unei firme ?id pentru ; a fi reactualizata cu preturile calulate in ciclul urmator de functionare. (defrule adaugare_pret_concurenta_in_lista ?f1 <- (adauga_pret_concurenta ?id ?vpic) ?f2 <- (preturi_concurenta ?id $?first) => (retract ?f1 ?f2) (assert (preturi_concurenta ?id $?first ?vpic)) ) (defrule calcul_medie_preturi_concurenta (declare (salience -3)) ?f <- (preturi_concurenta ?id $?vp) (test (eq (length$ $?vp) ?*nfc*)) => (retract ?f) (assert (preturi_concurenta ?id) (medie_preturi_concurenta ?id (/ (+ (expand$ $?vp)) (length$ $?vp))) ) ) (defrule adaugare_beneficiu_firma_in_lista_1 (or ?f <- (valoare_beneficiu ?tip &~pret_intarziat ?id ? ?vb) ?f <- (valoare_beneficiu ?tip &pret_intarziat ? ?id ?vb) ) (not (lista_beneficii ?tip ?id $?)) => (retract ?f) (assert (lista_beneficii ?tip ?id ?vb)) ) (defrule adugare_beneficiu_firma_in_lista_2 (or ?f1 <- (valoare_beneficiu ?tip &~pret_intarziat ?id ? ?vb) ?f1 <- (valoare_beneficiu ?tip &pret_intarziat ? ?id ?vb) ) ?f2 <- (lista_beneficii ?tip ?id $?lvb) => (retract ?f1 ?f2) (assert (lista_beneficii ?tip ?id $?lvb ?vb)) ) (defrule calcul_beneficiu_mediu_firma (declare (salience -3)) ?f <- (lista_beneficii ?tip ?id $?vb) (test (eq (length$ $?vb) ?*nfc*)) => (retract ?f) (assert (beneficiu_mediu ?tip ?id (/ (+ (expand$ $?vb)) ?*nfc*)) ) ) ;============================================================================ ; ; REGULI PENTRU MODIFICAREA PRETURILOR ; ;============================================================================ ; STRATEGIE: COMP-PROFIT ; Regulile urmatoare compara beneficiul obtinut de firma la pretul actual ; practicat de aceasta, cu beneficiul mediu obtinut de concurenta la pret ; intarziat si se stabilesc modificarile ce vor fi efectuate: ; Daca beneficul firmei este mai mic: ; - se compara pretul actual cu "media" preturilor firmelor concurente si ; daca acesta este mai mare/mic decat aceasta media se realizeaza o ; scadere/crestere a pretului ; Daca beneficul firmei este mai mare: ; - se va evalua beneficiul obtinut daca produsul firmei ar avea un pret ; actual mai mare / mai mic (op. de maximizare) (defrule modificare_pret_daca_beneficiu_mic (declare(salience -6)) (strategie ?id comp-profit) (lista_preturi ?id ?vp1 $?) ?f1 <- (medie_preturi_concurenta ?id ?vp2) (beneficiu_mediu pret_actual ?id ?vb1) ?f2 <- (beneficiu_mediu pret_intarziat ?id ?vb2 &:(< ?vb1 ?vb2)) => (retract ?f1 ?f2) (if (<= ?vp1 ?vp2) then (assert (valoare_pret ?id creste)) else (assert (valoare_pret ?id scade)) ) ) (defrule modificare_pret_daca_beneficiu_mare (declare(salience -5)) (strategie ?id comp-profit) (beneficiu_mediu pret_actual ?id ?vb1) ?f1 <- (beneficiu_mediu pret_intarziat ?id ?vb2 &:(>= ?vb1 ?vb2)) ?f2 <- (medie_preturi_concurenta ?id ?vp2) => (retract ?f1 ?f2) (assert (evaluare_beneficiu ?id)) ) ; Se modifica pretul pentru a obtine un beneficiu mai mare (op. de maximizare) ; realizata cu strategia max-profit (defrule eliminare_fapt_flag (declare (salience -4)) ?f <- (evaluare_beneficiu ?id) => (retract ?f ) ) ; STRATEGIE: MAX-PROFIT ; Firma nu mai tine cont de beneficul (preturile) concurentei atunci cand ; isi modifica pretul de vanzare, singurul scop imediat fiind de asi maximiza ; profitul. In functie de valorile beneficiilor obtinute la un pret mai ; ridicat / scazut se ia decizia de a pastra acelasi pret sau de al modifica. ; Regula este aproape identica cu 'modificare_pret_daca_beneficiu_mare'. (defrule modificare_pret_functie_de_beneficiul_maxim (declare (salience -6)) (beneficiu_mediu pret_actual ?id ?vbpa) ?f1 <- (beneficiu_mediu pret_mai_ridicat ?id ?vbpr) ?f2 <- (beneficiu_mediu pret_mai_scazut ?id ?vbps) => (retract ?f1 ?f2) (switch (max ?vbpa ?vbpr ?vbps) (case ?vbps then (assert (valoare_pret ?id scade)) ) (case ?vbpa then (assert (valoare_pret ?id aceiasi)) ) (case ?vbpr then (assert (valoare_pret ?id creste)) ) ) ) ; Se modifica listele de preturi punand in fata noul pret si eliminand ; ultimul element din lista (pentru a pastra dimensiunile listelor) (defrule valoare_pret_creste (declare (salience -15)) ?f1 <- (lista_preturi ?id ?vp $?lista) ?f2 <- (valoare_pret ?id creste) (or (and ?f3 <- (valoare_increment ?id ?incr) (tip-increment ?id ?tip &fuzzy)) ?f3 <- (tip-increment ?id ?tip &fix ?incr) ) => (retract ?f1 ?f2) (if (eq ?tip fuzzy) then (retract ?f3)) (if (< (+ ?vp ?incr) (get-u-to pret)) then (bind ?lista (create$ (+ ?vp ?incr) ?vp $?lista)) else (bind ?lista (create$ (get-u-to pret) ?vp $?lista)) ) (assert (lista_preturi ?id (subseq$ $?lista 1 (- (length$ $?lista) 1)))) ) (defrule valoare_pret_scade (declare (salience -15)) ?f1 <- (lista_preturi ?id ?vp $?lista) ?f2 <- (valoare_pret ?id scade) (or (and ?f3 <- (valoare_increment ?id ?incr) (tip-increment ?id ?tip &fuzzy)) ?f3 <- (tip-increment ?id ?tip &fix ?incr) ) => (retract ?f1 ?f2) (if (eq ?tip fuzzy) then (retract ?f3)) (if (> (- ?vp ?incr) (get-u-from pret)) then (bind ?lista (create$ (- ?vp ?incr) ?vp $?lista)) else (bind ?lista (create$ (get-u-from pret) ?vp $?lista)) ) (assert (lista_preturi ?id (subseq$ $?lista 1 (- (length$ $?lista) 1)))) ) (defrule aceiasi_valoare_pret (declare (salience -15)) ?f1 <- (lista_preturi ?id ?vp $?lista) ?f2 <- (valoare_pret ?id aceiasi) (or (and ?f3 <- (valoare_increment ?id ?incr) (tip-increment ?id ?tip &fuzzy)) ?f3 <- (tip-increment ?id ?tip &fix ?incr) ) => (retract ?f1 ?f2) (if (eq ?tip fuzzy) then (retract ?f3)) (assert (lista_preturi ?id ?vp ?vp (subseq$ $?lista 1 (- (length$ $?lista) 1)))) ) ;============================================================================ ; ; CONSTRUCTII + REGULI FUZZY INCREMENT ; ;============================================================================ (deftemplate dif_profit -90 90 ((large_negative (-40 1) (-15 0)) (negative (-40 0) (-15 1) (0 0)) (zero (-15 0) (0 1) (15 0)) (positive (0 0) (15 1) (40 0)) (large_positive (15 0) (40 1)) ) ) (deftemplate increment 0 2 USD ((mic (0 1) (0.3 0)) (mediu (0.2 0) (0.4 1) (0.7 0)) (mare (0.5 0) (1 1)) ) ) (defrule dif_profit_large_negative (dif_profit large_negative) => (assert (increment mare)) ) (defrule dif_profit_negative (dif_profit negative) => (assert (increment mediu)) ) (defrule dif_profit_zero (dif_profit zero) => (assert (increment mic)) ) (defrule dif_profit_positive (dif_profit positive) => (assert (increment mediu)) ) (defrule dif_profit_large_positive (dif_profit large_positive) => (assert (increment mare)) ) (defrule fuzificare_diferenta_beneficii (declare (salience -4)) (tip-increment ?id fuzzy) (beneficiu_mediu pret_actual ?id ?vbmpa) ?f <- (beneficiu_mediu pret_intarziat ?id ?vbmpi) (strategie ?id ?str) => (if (eq ?str max-profit) then (retract ?f) ) ; (if (< (abs(- ?vbmpa ?vbmpi)) 1) ; then (assert (valoare_increment ?id 0))) !!!!!!! ; else (assert (calcul_increment ?id) (dif_profit (PI 0 (- ?vbmpa ?vbmpi)) )) ; ) ) (defrule calcul_valoare_crisp_increment (declare (salience -1)) (tip-increment ?id fuzzy) ?f1 <- (increment ?) ?f2 <- (calcul_increment ?id) ?f3 <- (dif_profit ?) => (retract ?f1 ?f2 ?f3) (assert (valoare_increment ?id (moment-defuzzify ?f1))) )