;;;====================================================== ;;; Spare Part Business Planning Fuzzy Expert System ;;; ;;; ;;; ;;; FuzzyCLIPS Version 6.0 Example ;;; ;;; To execute, merely load, reset, and run. ;;;====================================================== (deftemplate delay ;;; how long do customers have to wait 0 0.7 units ;;; normalized "universe of discourse " ( (veryshort (0.1 1) ( 0.3 0) ) (short ( 0.1 0 ) ( 0.3 1) (0.5 0 ) ) ( medium ( 0.4 0 ) ( 0.6 1 ) ) ;;; we never have customers wait a long time! ) ) (deftemplate workers ;;; how many workers do we have 0 1 units ;;; normalized "universe of discourse " ( (small (0.15 1) ( 0.35 0) ) (medium ( 0.3 0 ) ( 0.5 1) (0.7 0 ) ) ( large (0.6 0) (0.8 1) ) ) ) (deftemplate utilization ;;; how busy the shop is 0 1 units ;;; normalized "universe of discourse " ( (low (0.4 1) ( 0.6 0) ) (medium (0.4 0) ( 0.6 1) ( 0.8 0) ) (high (0.6 0) (0.8 1) ) ;; everything up is high ) ) (deftemplate spares ;;; how many spare parts to start out with - to be predicted 0 1 units ;;; normalized "universe of discourse " ( ( verysmall (0.1 1) ( 0.30 0) ) ( small (0 0) (0.2 1) (0.4 0) ) ( rathersmall (0.25 0 ) (0.35 1) (0.45 0) ) ( medium (0.3 0) (0.50 1) (0.70 0) ) ( ratherlarge (0.55 0) (0.65 1) (0.75 0) ) ( large (0.6 0) (0.8 1) (1 0) ) ( verylarge (0.7 0) (0.9 1) ) ) ) (defrule lowutilrule1 "if it is not busy then don't keep a lot of spares" (declare (cf 1.0)) ; ?f1 <- (utilization low) => (bind ?util (moment-defuzzify ?f1)) (bind ?utilclipped (get-fs-value (create-fuzzy-value utilization low) ?util )) (printout t "> debug in lowutilrule1 " t " how heavy is utilization? " ?util t " membership in low : " ?utilclipped t " asserting small number of spares " t ) (assert (spares small) ) ) (defrule medutilrule1 "if it is somewhat busy then keep a medium number of spares" (declare (cf 1.0)) ; ?f1 <- (utilization medium) => (bind ?util (moment-defuzzify ?f1)) (bind ?utilclipped (get-fs-value (create-fuzzy-value utilization medium) ?util )) (printout t "> debug in medutilrule1 " t " how heavy is utilization? " ?util t " membership in medium: " ?utilclipped t " asserting medium number of spares " t ) (assert (spares medium) ) ) (defrule highutilrule1 "if it is busy then keep a lot of spares" (declare (cf 1.0)) ; ?f1 <- (utilization high) => (bind ?util (moment-defuzzify ?f1)) (bind ?utilclipped (get-fs-value (create-fuzzy-value utilization high) ?util )) (printout t "> debug in highutilrule1 " t " how heavy is utilization? " ?util t " membership in high: " ?utilclipped t " asserting large number of spares " t ) (assert (spares large) ) ) (defrule delayserversrule1 "if delay is to be very short and have small number of employees then keep a very large number of spares" (declare (cf 1.0)) ; ?f1 <- (delay veryshort) ?f2 <- (workers small) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay veryshort) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers small) ?workers )) (printout t "> debug in delayserversrule1 " t " how long a delay is it? " ?delay t " membership in veryshort : " ?delayclipped t " how many workers are there? " ?workers t " membership in small: " ?workersclipped t " asserting verylarge number of spares " t ) (assert (spares verylarge) ) ) (defrule delayserversrule2 "if delay is to be short and have small number of employees then keep a large number of spares" (declare (cf 1.0)) ; ?f1 <- (delay short) ?f2 <- (workers small) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay short) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers small) ?workers )) (printout t "> debug in delayserversrule2" t " how long a delay is it? " ?delay t " membership in short : " ?delayclipped t " how many workers are there? " ?workers t " membership in small: " ?workersclipped t " asserting large number of spares " t ) (assert (spares large) ) ) (defrule delayserversrule3 "if delay is to be medium and have small number of employees then keep a medium number of spares" (declare (cf 1.0)) ; ?f1 <- (delay medium) ?f2 <- (workers small) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay medium) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers small) ?workers )) (printout t "> debug in delayserversrule3 " t " how long a delay is it? " ?delay t " membership in medium: " ?delayclipped t " how many workers are there? " ?workers t " membership in small: " ?workersclipped t " asserting medium number of spares " t ) (assert (spares medium) ) ) (defrule delayserversrule4 "if delay is to be very short and have medium number of employees then keep a rather large number of spares" (declare (cf 1.0)) ; ?f1 <- (delay veryshort) ?f2 <- (workers medium) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay veryshort) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers medium) ?workers )) (printout t "> debug in delayserversrule4 " t " how long a delay is it? " ?delay t " membership in veryshort : " ?delayclipped t " how many workers are there? " ?workers t " membership in medium: " ?workersclipped t " asserting ratherlarge number of spares " t ) (assert (spares ratherlarge) ) ) (defrule delayserversrule5 "if delay is to be short and have medium number of employees then keep a rather small number of spares" (declare (cf 1.0)) ; ?f1 <- (delay short) ?f2 <- (workers medium) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay short) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers medium) ?workers )) (printout t "> debug in delayserversrule5 " t " how long a delay is it? " ?delay t " membership in short: " ?delayclipped t " how many workers are there? " ?workers t " membership in medium: " ?workersclipped t " asserting rathersmall number of spares " t ) (assert (spares rathersmall) ) ) (defrule delayserversrule6 "if delay is to be medium and have medium number of employees then keep a small number of spares" (declare (cf 1.0)) ; ?f1 <- (delay medium) ?f2 <- (workers medium) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay medium) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers medium) ?workers )) (printout t "> debug in delayserversrule6 " t " how long a delay is it? " ?delay t " membership in medium: " ?delayclipped t " how many workers are there? " ?workers t " membership in medium: " ?workersclipped t " asserting small number of spares " t ) (assert (spares small) ) ) (defrule delayserversrule7 "if delay is to be very short and have large number of employees then keep a medium number of spares" (declare (cf 1.0)) ; ?f1 <- (delay veryshort) ?f2 <- (workers large) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay veryshort) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers large) ?workers )) (printout t "> debug in delayserversrule7 " t " how long a delay is it? " ?delay t " membership in veryshort : " ?delayclipped t " how many workers are there? " ?workers t " membership in large: " ?workersclipped t " asserting medium number of spares " t ) (assert (spares medium) ) ) (defrule delayserversrule8 "if delay is to be short and have large number of employees then keep a small number of spares" (declare (cf 1.0)) ; ?f1 <- (delay short) ?f2 <- (workers large) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay short) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers large) ?workers )) (printout t "> debug in delayserversrule8 " t " how long a delay is it? " ?delay t " membership in short : " ?delayclipped t " how many workers are there? " ?workers t " membership in large: " ?workersclipped t " asserting small number of spares " t ) (assert (spares small) ) ) (defrule delayserversrule9 "if delay is to be medium and have large number of employees then keep a very small number of spares" (declare (cf 1.0)) ; ?f1 <- (delay medium) ?f2 <- (workers large) => (bind ?delay (moment-defuzzify ?f1)) (bind ?workers (moment-defuzzify ?f2)) (bind ?delayclipped (get-fs-value (create-fuzzy-value delay medium) ?delay )) (bind ?workersclipped (get-fs-value (create-fuzzy-value workers large) ?workers )) (printout t "> debug in delayserversrule9 " t " how long a delay is it? " ?delay t " membership in medium: " ?delayclipped t " how many workers are there? " ?workers t " membership in large: " ?workersclipped t " asserting verysmall number of spares " t ) (assert (spares verysmall) ) ) (defrule answerrule " specify the answer with certainty factor" (dontusefor this) ?f <- (spares ?answ) => (printout t t " The recommendation is " ?answ " with certainty factor " (get-cf ?f) t ) ) ; the next rule takes the result of the previous rules and produces a non-fuzzy ; result to identify the amount (between 0 and 1) of spares to suggest ; and finally prints out the de-fuzzified (but still normalized) result (defrule get-crisp-value-and-print-rslt (declare (salience 1)) ?pr <- (spares ?) => (bind ?f (moment-defuzzify ?pr)) (plot-fuzzy-value t "+" nil nil ?pr) ;;(bind ?f (maximum-defuzzify ?pr)) (printout t "So far, would Recommend Normalized Number of Spares to Start out With of: " ?f " " (get-u-units ?pr) " (go with last recommendation)" crlf) )