git.fiddlerwoaroof.com
Raw Blame History
;;; Sample OPS5 expanded program
;;; 
;;; Author: Michael Mauldin 3/23/84
;;; 
;;; References: These rules are based on rules from Nelson, William R.,
;;; "REACTOR: An Expert System for Diagnosis and Treatment of Nuclear
;;; Reactor Accidents," Proceedings of AAAI 1982.

(reset-ops)

(strategy lex)
(watch 0)
(literalize fact
    system name value trend status raw-value change)

(literalize task
    goal subgoal query)

(literalize accident
    type id)

(literalize trace
    elt)

(vector-attribute
    elt)

(p start				; Start the diagnosis
    (ready)
    -->
    (write (crlf) "Enter id number for this run:  ")
    (bind <id> (accept))
    (make task ^goal input)
    (make accident ^id <id>)
    (make fact ^system containment ^name pressure ^trend unknown)
    (make fact ^system containment ^name radiation ^value unknown)
    (make fact ^system feedwater ^name flow ^value unknown)
    (make fact ^system pcs ^name pressure ^trend unknown)
    (make fact ^system pcs ^name temperature ^trend unknown)
    (make fact ^system sg ^name level ^trend unknown)
    (make fact ^system steam ^name flow ^value unknown)
    (make fact ^system hpis ^status unknown)
    (write (crlf)))

;;; Get  numeric values for variables that require a high/steady/low
;;; determination.   Store in the raw-value slot.

(p get-value
    (task ^goal input)
    (fact ^system <system> ^name <name> ^value unknown ^raw-value nil)
    -->
    (write "Enter value for" <system> <name> "[1..100]: ")
    (bind <value> (accept))
    (modify 2 ^raw-value <value>))

;;; Get old and new values for variables which have a trend
;;; increasing/decreasing/steady.  Store the difference in the change
;;; slot.

(p get-trend
    (task ^goal input)
    (fact ^system <system> ^name <name> ^trend unknown ^change nil)
    -->
    (write "Enter old value for" <system> <name> "[1..100]: ")
    (bind <old> (accept))
    (write "Enter new value for" <system> <name> "[1..100]: ")
    (bind <new> (accept))
    (modify 2 ^change (compute <new> - <old>)))

;;; get the status for systems

(p get-status
    (task ^goal input)
    (fact ^system <system> ^name nil ^status unknown)
    -->
    (write "Enter value for" <system> "[on, off]: ")
    (bind <value> (accept))
    (modify 2 ^status <value>))

;;; After all variables requiring user input have been set, set the
;;; goal to classify the inputs in terms of low/high/nominal,
;;; increasing/decreasing/steady.

(p end-of-input
    (task ^goal input)
    -->
    (modify 1 ^goal classify)
    (write (crlf) "Starting classification..." (crlf)))

;;; The next three rules set the value slot based on the raw numeric
;;; value.  Rather than define various nominal values, I have used a
;;; dimensionless numeric scale where 1-32 are low, 33-66 are nominal,
;;; and 67-100 are high.

(p classify-low
    (task ^goal classify)
    (fact ^system <system> ^name <name> ^raw-value < 33 ^value unknown)
    -->
    (modify 2 ^value low)
    (write "Rule classify-low concludes that" <system> <name>
           "is low" (crlf)))

(p classify-high
    (task ^goal classify)
    (fact ^system <system> ^name <name> ^raw-value > 66 ^value unknown)
    -->
    (modify 2 ^value high)
    (write "Rule classify-high concludes that" <system> <name> 
           "is high" (crlf)))

(p classify-nominal
    (task ^goal classify)
    (fact ^system <system> ^name <name> ^value unknown)
    -->
    (modify 2 ^value nominal)
    (write "Rule classify-nominal concludes that" <system> <name> 
            "is nominal" (crlf)))

;;; The next three rules classify a trend. If the change from the old
;;; value to the new one is 3 units or less, the variable is labelled
;;; 'steady,' otherwise it is marked as either increasing or decreasing.
(p classify-decreasing
    (task ^goal classify)
    (fact ^system <system> ^name <name> ^trend unknown ^change {<change> < -3})
    -->
    (modify 2 ^trend decreasing)
    (write "Rule classify-decreasing concludes that" <system> <name>
           "is decreasing" (crlf)))

(p classify-increasing
    (task ^goal classify)
    (fact ^system <system> ^name <name> ^trend unknown ^change {<change> > 3})
    -->
    (modify 2 ^trend increasing)
    (write "Rule classify-increasing concludes that" <system> <name>
           "is increasing" (crlf)))

(p classify-steady
    (task ^goal classify)
    (fact ^system <system> ^name <name> ^trend unknown)
    -->
    (modify 2 ^trend steady)
    (write "Rule classify-steady concludes that" <system> <name>
           "is steady" (crlf)))

;;; After all variables have been classified, start the diagnosis

(p start-diagnosis
    (task ^goal classify)
    -->
    (modify 1 ^goal diagnose)
    (write (crlf) "Starting diagnosis..." (crlf)))

(p rule-1				; PCS Integrity challenged?
    (task ^goal diagnose)
    (fact ^system pcs ^name pressure ^trend decreasing)
    (fact ^system hpis ^status on)
    -->
    (make fact ^system pcs ^name integrity ^status challenged)
    (write "Rule 1 concludes:    "  pcs integrity challenged (crlf))
    (make trace rule-1 used pcs pressure decreasing)
    (make trace rule-1 used hpis on))

(p rule-2				; Heat transfer inadequate?
    (task ^goal diagnose)
    (fact ^system pcs ^name temperature ^trend increasing)
    -->
    (make fact ^system pcs ^name heat-transfer ^status inadequate)
    (write "Rule 2 concludes:    "  pcs heat-transfer inadequate (crlf))
    (make trace rule-2 used pcs temperature increasing))

(p rule-3				; SG inventory inadequate?
    (task ^goal diagnose)
    (fact ^system sg ^name level ^trend decreasing)
    -->
    (make fact ^system sg ^name inventory ^status inadequate)
    (write "Rule 3 concludes:    "  sg inventory inadequate (crlf))
    (make trace rule-3 used sg level decreasing))

(p rule-4				; Containment integrity challenged?
    (task ^goal diagnose)
    (fact ^system containment ^name radiation ^value high)
    (fact ^system containment ^name pressure ^value high)
    -->
    (make fact ^system containment ^name integrity ^status challenged)
    (write "Rule 4 concludes:    "  containment integrity challenged (crlf))
    (make trace rule-4 used containment radiation high)
    (make trace rule-4 used containment pressure high))

(p rule-5				; Loss of feedwater?
    (task ^goal diagnose)
    (accident ^id <id>)
    (fact ^system pcs ^name heat-transfer ^status inadequate)
    (fact ^system feedwater ^name flow ^value low)
    -->
    (modify 2 ^type loss-of-feedwater)
    (write "Rule 5 concludes accident is loss of feedwater" (crlf))
    (modify 1 ^goal explain)
    (make trace rule-5 used pcs heat-transfer inadequate)
    (make trace rule-5 used feedwater flow low))

(p rule-6				; Loss of feedwater?
    (task ^goal diagnose)
    (accident ^id <id>)
    (fact ^system sg ^name inventory ^status inadequate)
    (fact ^system feedwater ^name flow ^value low)
    -->
    (modify 2 ^type loss-of-feedwater)
    (write "Rule 6 concludes accident is loss of feedwater" (crlf))
    (modify 1 ^goal explain)
    (make trace rule-6 used sg inventory inadequate)
    (make trace rule-6 used feedwater flow low))

(p rule-7				; Loss of coolant?
    (task ^goal diagnose)
    (accident ^id <id>)
    (fact ^system pcs ^name integrity ^status challenged)
    (fact ^system containment ^name integrity ^status challenged)
    -->
    (modify 2 ^type loca)
    (write "Rule 7 concludes accident is loss of coolant" (crlf))
    (modify 1 ^goal explain)
    (make trace rule-7 used pcs integrity challenged)
    (make trace rule-7 used containment integrity challenged))

(p rule-8				; SG tube rupture?
    (task ^goal diagnose)
    (accident ^id <id>)
    (fact ^system pcs ^name integrity ^status challenged)
    (fact ^system sg ^name level ^trend increasing)
    -->
    (modify 2 ^type sg-tube-rupture)
    (write "Rule 8 concludes accident is steam generator tube rupture" (crlf))
    (modify 1 ^goal explain)
    (make trace rule-8 used pcs integrity challenged)
    (make trace rule-8 used sg level increasing))

(p rule-9				; Steam line break?
    (task ^goal diagnose)
    (accident ^id <id>)
    (fact ^system sg ^name inventory ^status inadequate)
    (fact ^system steam ^name flow ^value high)
    -->
    (modify 2 ^type steam-line-break)
    (write "Rule 9 concludes accident is steam line break" (crlf))
    (modify 1 ^goal explain)
    (make trace rule-9 used sg inventory inadequate)
    (make trace rule-9 used steam flow high))

(p no-diagnosis
    (task ^goal diagnose)
    -->
    (write "No diagnosis" (crlf))
    (modify 1 ^goal explain))

;;; Explanation:  Get a single word from the user, and then reply to
;;; those words we recognize.  Currently we recognize the following
;;; questions:
;;; 
;;; facts:	prints the facts used during diagnosis
;;; high:	prints variables which are high
;;; low:	prints variables which are low
;;; nominal:	prints variables which are nominal
;;; increasing:	prints variables which are increasing
;;; decreasing:	prints variables which are decreasing
;;; steady:	prints variables which are steady

(p start-questions
    (task ^goal explain ^subgoal nil)
    -->
    (modify 1 ^subgoal prompt)
    (write (crlf) Starting explanations (crlf))
)

(p get-user-query
    (task ^goal explain ^subgoal prompt)
    -->
    (write "Explanations [facts, high/low, none]: ")
    (modify 1 ^subgoal reply ^query (acceptline none)))

;;; Print a line for each trace element

(p explain-facts
    (task ^goal explain ^subgoal reply ^query facts)
    (trace)
    -->
    (write "    Fact used: " (substr 2 2 inf) (crlf)))

;;; Print system values

(p explain-value
    (task ^goal explain ^subgoal reply ^query {<type> <> nil})
    (fact ^system <system> ^name <name> ^raw-value <value> ^value = <type>)
    -->
    (write "   " <type> ":" <system> <name> <value> (crlf)))

;;; Print trends

(p explain-trends
    (task ^goal explain ^subgoal reply ^query {<type> <> nil})
    (fact ^system <system> ^name <name> ^change <change> ^trend = <type>)
    -->
    (write "   " <type> ":" <system> <name> changed <change> (crlf)))

;;; Having answered the query, set up to ask for another

(p finish-this-query
    (task ^goal explain ^subgoal reply ^query <> none)
    -->
    (modify 1 ^subgoal prompt))

;;; No more queries, mark the task finished

(p quit
    (task ^goal explain ^subgoal reply ^query none)
    -->
    (modify 1 ^goal finished))