;;; 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))