⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shwrnoui.clp

📁 模糊clips专家系统
💻 CLP
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Global definitions used in the simulation
;;

(defglobal 

   ?*coldValvePos*     = 0.0
   ?*hotValvePos*      = 0.0
   ?*coldTemp*         = 0.0
   ?*hotTemp*          = 0.0
   ?*coldPress*        = 0.0
   ?*hotPress*         = 0.0
   ?*optimalTempMin*   = 34.0
   ?*optimalTempMax*   = 38.0
   ?*optimalFlowMin*   = 11.0
   ?*optimalFlowMax*   = 13.0
   ?*atmosphericPress* = 30.0
   ?*iterationFactor*  = 1.0
)



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Deftemplates below define the fuzzy variables being used
;;
;;
;; Outputs of the shower
;;
;;   outTemp  -- output temperature
;;
;;  outFlow   -- flow out of the shower

(deftemplate outTemp
   5 65 Celcius
  ((none  (5 1) (5.1 0))
   (cold  (z 10 35))
   (OK    (pi  2 36))
   (hot   (s 37  60)) )
  ())

(deftemplate outFlow
   0 100 liters/minute
  ((none   (0 1) (0.05 0))
   (low    (z 3 11.5))
   (OK     (pi  1 12))
   (strong (s 12.5  25)) )
  () )
  
  
;; controls for hot and cold valve positions
;;


(deftemplate change_vc
   -1 1
  ((NB (-0.5 1) (-.25 0))
   (NM  (-.35 0) (-.3 1) (-.15 0))
   (NS (-.25 0) (-.15 1) (0 0))
   (Z (-.05 0) (0 1) (.05 0))
   (PS (0 0) (.15 1) (.25 0))
   (PM (.15 0) (.3 1) (.35 0))
   (PB (.25 0)(0.5 1)) )
  ( ; modifier definitions
;        (very         sqr)
;        (less         sqrt)
  )
)


(deftemplate change_vh
   -1 1
  ((NB (-0.5 1) (-.25 0))
   (NM  (-.35 0) (-.3 1) (-.15 0))
   (NS (-.25 0) (-.15 1) (0 0))
   (Z (-.05 0) (0 1) (.05 0))
   (PS (0 0) (.15 1) (.25 0))
   (PM (.15 0) (.3 1) (.35 0))
   (PB (.25 0)(0.5 1)) )
  ( ; modifier definitions
;        (very         sqr)
;        (less         sqrt)
  )
)



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Some supporting functions
;;
;; getNumber  - requests a number in a given range
;;
;; ask-question - asks a question and gets answer from provided 
;;                allowed responses
;;
;; yes-or-no-p - requests a yes or no answer to given question
;;               (uses ask-question)
;;
;; initShower - initializes certain global values and requests some
;;              initial values from the user and calls simulate to
;;              calc the out flow and temp and assert these as
;;              fuzzy facts to start the fuzzy rules going
;;
;; Simulate   - calculates the new outFlow and outTemp when changes
;;              to valve positions are made -- also asserts the
;;              fuzzified facts representing these new values --
;;              also checks for finished state (temp and flow in range
;;              or for certain error conditions
;;


(deffunction getNumber (?question ?from ?to)
  (printout t ?question " [" ?from " to " ?to "]: ")
  (bind ?answer (read))
  (while (not (and (numberp ?answer)
                   (>= ?answer ?from)
                   (<= ?answer ?to)
              )
         )
    do
      (printout t "Please enter a numeric answer within the specified range" crlf 
                  ?question " [" ?from " to " ?to "]: ")
      (bind ?answer (read))
  )
  ?answer
)


(deffunction ask-question (?question $?allowed-values)
   (printout t ?question)
   (bind ?answer (read))
   (if (lexemep ?answer) 
       then (bind ?answer (lowcase ?answer)))
   (while (not (member ?answer ?allowed-values)) do
      (printout t ?question)
      (bind ?answer (read))
      (if (lexemep ?answer) 
          then (bind ?answer (lowcase ?answer))))
   ?answer)


(deffunction yes-or-no-p (?question)
   (bind ?response (ask-question ?question yes no y n))
   (if (or (eq ?response yes) (eq ?response y))
       then TRUE 
       else FALSE))



(deffunction Simulate (?coldValveChange ?hotValveChange)

  ;; Check for some rather bad situations where control is lost
  ;;
  (if (and (= ?*coldValvePos* 1.0) (> ?coldValveChange 0.0) (>= ?hotValveChange 0.0))
    then
      (printout t crlf "*** Cold Water Problem -- Cold valve full open and trying to open more ***" crlf
                       "Stopping simulation" crlf)
                       
      (bind ?*iterationFactor* 1.0)  ;; reset iteration Factor
      (halt)
  )
  (if (and (= ?*hotValvePos* 1.0) (> ?hotValveChange 0.0) (>= ?coldValveChange 0.0))
    then
      (printout t crlf "*** Hot Water Problem -- Hot valve full open and trying to open more ***" crlf
                       "Stopping simulation" crlf)
                       
      (bind ?*iterationFactor* 1.0)  ;; reset iteration Factor
      (halt)
  )
  (if (and (= ?*coldValvePos* 0.0) (< ?coldValveChange 0.0) (< (abs  ?hotValveChange) 0.000001)) 
    then
      (printout t crlf "*** HOT TEMPERATURE PROBLEM ***" crlf
                       "Shutting down - cannot get temperature high enough" crlf )
                       
      (bind ?*iterationFactor* 1.0)  ;; reset iteration Factor
      (halt)
  )
  (if (and (= ?*hotValvePos* 0.0) (< ?hotValveChange 0.0) (< (abs ?coldValveChange) 0.000001)) 
    then
      (printout t crlf "*** HOT TEMPERATURE PROBLEM ***" crlf
                       "Shutting down - cannot get temperature low enough" crlf )

      (bind ?*iterationFactor* 1.0)  ;; reset iteration Factor
      (halt)
  )
  
  ;; calc new hot and cold valve positions based on the recommendations
  ;; for change provided 
  ;; NOTE: we perform a scaling factor on the recommendations making the assumption
  ;;       that at high valve settings a change will produce less effect than
  ;;       if we are operating at a low valve setting; this is due to the effect
  ;;       of pressures -- low pressures will tend to put us at higher valve
  ;;       positions; of course in a REAL situation the actual operating conditions
  ;;       of the system would likely be known and we couuld adjust accordingly;
  ;;       One problem that can occur is that the adjustments cause the system
  ;;       to be too course in its adjustment and it makes a change to go up and then
  ;;       a symmetric change to go down -- it will then endlessly flip flop between
  ;;       a too high and a too low condition -- this is solved by reducing the scale
  ;;       factor after each iteration so the adjustments get smaller and smaller.
  ;;       Also note that we could also tune the fuzzy sets to reduce the range 
  ;;       of changes recommended.
  ;;       REMEMBER the conditions of the problem -- we do not know the temps or
  ;;       pressures of hot and cold supplies
  
  (if (or (<> ?coldValveChange 0.0) (<> ?hotValveChange 0.0))
     then
       (bind ?*coldValvePos* 
                 (max 0.0
                      (min 1.0 
                           (+ ?*coldValvePos* 
                              (* (* (max 0.1 ?*coldValvePos*) ?*iterationFactor*)
                                 ?coldValveChange
                              )
                           )
                      )
                 )
       )
       (bind ?*hotValvePos* 
                 (max 0.0
                      (min 1.0 
                           (+ ?*hotValvePos* 
                              (* (* (max 0.1 ?*hotValvePos*) ?*iterationFactor*)
                                 ?hotValveChange
                              )
                           )
                      )
                 )
       )
       (format t "Cold Valve Position = %5.3f, Hot  Valve Position = %5.3f %n" 
                  ?*coldValvePos* ?*hotValvePos* 
       )
   )
   (bind ?hotFlow (* ?*hotValvePos* (- ?*hotPress* ?*atmosphericPress*)))
   (bind ?coldFlow (* ?*coldValvePos* (- ?*coldPress* ?*atmosphericPress*)))
   (bind ?outFlow (+ ?hotFlow ?coldFlow))
   (if (= ?outFlow 0.0)
      then
         (bind ?outTemp 5.0)
      else
         (bind ?outTemp (/ (+ (* ?coldFlow ?*coldTemp*)
                              (* ?hotFlow ?*hotTemp*))
                           ?outFlow)
         )
   )
   (format t "Output Flow is %6.3f litres/sec%n" ?outFlow)
   (format t "Output Temp is %6.3f degrees C%n" ?outTemp)
   
   ;; if both output flow and temp are within correct range control is
   ;; completed -- pause to ask for changes to input temps or pressures
   ;; or to quit
   ;;
   
   (if (and (and (> ?outFlow ?*optimalFlowMin*) (< ?outFlow ?*optimalFlowMax*))
            (and (> ?outTemp ?*optimalTempMin*) (< ?outTemp ?*optimalTempMax*))
       )
      then    
        (printout t "Shower is under control!" crlf)
        (bind ?*iterationFactor* 1.0)  ;; reset iteration Factor
        (if (yes-or-no-p "Would you like to change some parameters? ")
          then
            (bind ?*coldTemp* (getNumber "New Temperature (Celcius) of cold water input?" 5 65))
            (bind ?*hotTemp* (getNumber "New Temperature (Celcius) of hot water input?" 5 65))
            (bind ?*coldPress* (getNumber "New Pressure (kPa) of cold water input?" 42 100))
            (bind ?*hotPress* (getNumber "New Pressure (kPa) of hot water input?" 42 100))       
            ;; need to recalc Fow and Temp since things changed
            (bind ?hotFlow (* ?*hotValvePos* (- ?*hotPress* ?*atmosphericPress*)))
            (bind ?coldFlow (* ?*coldValvePos* (- ?*coldPress* ?*atmosphericPress*)))
            (bind ?outFlow (+ ?hotFlow ?coldFlow))
            (if (= ?outFlow 0.0)
              then
               (bind ?outTemp 5.0)
              else
               (bind ?outTemp (/ (+ (* ?coldFlow ?*coldTemp*)
                                    (* ?hotFlow ?*hotTemp*))
                                   ?outFlow)
               )
            )
            (format t "Output Flow is %6.3f litres/sec%n" ?outFlow)
            (format t "Output Temp is %6.3f degrees C%n" ?outTemp)
          else
            (bind ?*iterationFactor* 1.0)  ;; reset iteration Factor
            (halt)
        )
   )
   ;; iterationFactor reduces each cycle through
   (if (> ?*iterationFactor* 0.1)
     then
       (bind ?*iterationFactor* (* ?*iterationFactor* .96))
   )
   
   ;; now assert the fuzzified values of the Flow and Temp of Output
   (if (= ?outFlow 0.0)
     then
       (assert (outFlow (0.0 1.0) (0.5 0.0)))
     else
       (if (= ?outFlow 100.0)
         then
           (assert (outFlow (99.5 0.0) (100.0 1.0)))
         else
           (assert (outFlow ((max 0.0 (- ?outFlow 0.5)) 0.0) (?outFlow 1.0)
                            ((min 100.0 (+ ?outFlow 0.5)) 0.0) ))
       )
   )
   (if (= ?outTemp 5.0)
     then
       (assert (outTemp (5.0 1.0) (5.1 0.0)))
     else
       (if (= ?outTemp 65.0)
         then
           (assert (outTemp (64.9 0.0) (65.0 1.0)))
         else
           (assert (outTemp ((max 5.0 (- ?outTemp 0.1)) 0.0) (?outTemp 1.0)
                            ((min 65.0 (+ ?outTemp 0.1)) 0.0) ))
       )
   )
)




(deffunction initShower ()
   (bind ?*coldValvePos* (getNumber "Initial Cold Valve Position?" 0.0 1.0))
   (bind ?*hotValvePos* (getNumber "Initial Hot Valve Position?" 0.0 1.0))
   (bind ?*coldTemp* (getNumber "Initial Temperature (Celcius) of cold water input?" 5 65))
   (bind ?*hotTemp* (getNumber "Initial Temperature (Celcius) of hot water input?" 5 65))
   (bind ?*coldPress* (getNumber "Initial Pressure (kPa) of cold water input?" 42 100))
   (bind ?*hotPress* (getNumber "Initial Pressure (kPa) of hot water input?" 42 100))
   (Simulate 0.0 0.0)
)



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Initializing rule
;;

(defrule start
   =>
     (initShower) 
    )


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Rules that control the shower with fuzzy inferencing
;;

(defrule none_none "will jump start an off system"
   (outTemp none)
   (outFlow none)
   =>
   (assert (change_vh PS))
   (assert (change_vc PM))
)


(defrule cold_low
   (outTemp cold)
   (outFlow low)
   =>
   (assert (change_vh PB))
   (assert (change_vc Z))
)

(defrule cold_OK
    (outTemp cold)
    (outFlow OK)
   =>
    (assert (change_vh  PM))
    (assert (change_vc Z))
)

(defrule cold_strong
    (outTemp cold)
    (outFlow strong)
   =>
    (assert (change_vh Z))
    (assert (change_vc NB))
)

(defrule OK_low
   (outTemp OK)
   (outFlow low)
  =>
   (assert (change_vh  PS))
   (assert (change_vc  PS))
)

(defrule OK_strong
   (outTemp OK)
   (outFlow strong)
  =>
   (assert (change_vh  NS))
   (assert (change_vc NS))
)


(defrule hot_low
  (outTemp hot)
   (outFlow low)
  =>
   (assert (change_vh Z))
   (assert (change_vc  PB))
)

(defrule hot_OK
   (outTemp hot)
   (outFlow OK)
  =>
   (assert (change_vh NM))
   (assert (change_vc Z))
)

(defrule hot_strong
   (outTemp hot)
   (outFlow strong)
  =>
   (assert (change_vh NB))
   (assert (change_vc Z))
)

;; when all rules have fired and contributed to determination of the
;; control changes to be made then defuzzify the change values and
;; pass these new values to the simulate function

(defrule defuzzification-and-control
   (declare (salience -1))
   ?f1 <- (change_vc ?)
   ?f2 <- (change_vh ?)
   ?f3 <- (outTemp ?)
   ?f4 <- (outFlow ?)
 =>
   (bind ?coldChange (moment-defuzzify ?f1))
   (bind ?hotChange  (moment-defuzzify ?f2))
   (retract ?f1 ?f2 ?f3 ?f4)
   (Simulate ?coldChange ?hotChange)
)




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -