Here is my code
(deffacts startup
(bird canary)
(colour-canary yellow)
(bird ostrich)
(can-not-fly ostrich)
)
(defrule r-bird-test
(bird ?var)
(not (bird ostrich))
=>
(printout t ?var " ****" crlf)
)
Now, when i (reset) and (run) it doesn't print "canary ****". Am i not using the not condition properly? Can anyone point out what i am missing here? Thanks.
As written the not conditional element prevents the rule from executing if the fact (bird ostrich) is present. Since that fact is present once you perform a (reset), the rule does not execute. If you want the rule to execute for each bird fact where ?var is not ostrich, you need to write the rule this way:
CLIPS>
(deffacts startup
(bird canary)
(colour-canary yellow)
(bird ostrich)
(can-not-fly ostrich))
CLIPS>
(defrule r-bird-test
(bird ?var&~ostrich)
=>
(printout t ?var " ****" crlf))
CLIPS> (reset)
CLIPS> (run)
canary ****
CLIPS>
Related
this is a clips expert system code to make a diagnosis for a disease so i am trying to find out whats the problem in that code and i really dont know what to do
[CSTRCPSR1]
[CSTRCPSR2]
error
defrule diagnosis
(symptom ?s)
(disease (symptoms ?s) (name ?d))
=>
(printout t "The patient may have " ?d "." crlf))
(defrule ask-symptoms
(not (symptom ?))
=>
(bind ?symptom (read))
(assert (symptom ?symptom)))
(defrule ask-symptoms
(not (symptom ?))
=>
(printout t "What are the patient's symptoms?" crlf)
(bind ?symptom (read))
(assert (symptom ?symptom)))
(defrule ask-symptoms-2
(symptom ?s)
(not (symptom ?))
=>
(printout t "Any other symptom? " crlf)
(bind ?symptom (read))
(assert (symptom ?symptom)))
(defclass disease
(is-a USER)
(role concrete)
(multislot symptoms)
(slot name))
(definstances diseases
(disease (symptoms fever headache) (name "influenza"))
(disease (symptoms fever sorethroat) (name "strep throat"))
(disease (symptoms cough shortness-of-breath) (name "pneumonia"))
(disease (symptoms stomachache nausea) (name "food poisoning")))
i tried everything to fix it but i really dont know where is the problem
The diagnosis defrule is missing an opening parenthesis.
The diagnosis defrule references the disease defclass before the
class is defined.
Classes automatically have a name slot defined.
You have two ask-symptoms rules.
The conditions of the ask-symptoms-2 rule will never be satisfied.
Any fact matching the first pattern will cause the following pattern
to fail.
If you want to read multiple symptoms, use the readline function
along with the explode$ function.
In the diagnosis rule, you need to use the object keyword to match
an instance of a defclass.
In the diagnosis rule, the disease pattern can only be matched by
diseases with exactly one symptom.
For example:
CLIPS (6.4 2/9/21)
CLIPS>
(defclass disease
(is-a USER)
(role concrete)
(multislot symptoms)
(slot text))
CLIPS>
(defrule diagnosis
(object (is-a disease) (name ?name) (text ?d))
(exists
(symptoms $? ?s $?)
(object (is-a disease) (name ?name) (symptoms $? ?s $?)))
=>
(printout t "The patient may have " ?d "." crlf))
CLIPS>
(defrule ask-symptoms
=>
(printout t "What are the patient's symptoms? ")
(bind ?symptoms (readline))
(assert (symptoms (explode$ ?symptoms))))
CLIPS>
(definstances diseases
(influenza of disease (symptoms fever headache) (text "influenza"))
(strep-throat of disease (symptoms fever sorethroat) (text "strep throat"))
(pneumonia of disease (symptoms cough shortness-of-breath) (text "pneumonia"))
(food-poisoning of disease (symptoms stomachache nausea) (text "food poisoning")))
CLIPS> (reset)
CLIPS> (run)
What are the patient's symptoms? cough nausea
The patient may have pneumonia.
The patient may have food poisoning.
CLIPS>
So I'm trying to build a program that takes user's input by displaying a message on the screen “Enter your subject”.
In the second rule, I'm to mention subject names “artificial intelligence”, “operating system” and “compiler construction” and check that entered subject from the first rule matches with the mentioned subjects by displaying this message on the screen.
“Your entered subject is true”.
Here is the code:
(deftemplate subject
(slot subject)
(slot artificial intelligence)
(slot operating system)
(slot compiler construction))
(defrule reading-input
(printout t "Enter your subject:")
(assert(var(read))))
(defrule checking-input
(var? artificial intelligence)
(var? operating system)
(var? compiler construction)
(com(artificial intelligence ? artificial intelligence))
(test(=?artificial intelligence ? artificial intelligence))
(test(=?operating system ? operating system))
(test(=? compiler construction ? compiler construction))
(=>
printout t "Your entered subject is true:"))
CLIPS (6.31 6/12/19)
CLIPS>
(defrule reading-input
=>
(printout t "Enter your subject: ")
(assert (var (readline))))
CLIPS>
(defrule checking-input
(var "artificial intelligence" |
"operating system" |
"compiler construction")
=>
(printout t "Your entered subject is true." crlf))
CLIPS> (reset)
CLIPS> (run)
Enter your subject: operating system
Your entered subject is true.
CLIPS> (reset)
CLIPS> (run)
Enter your subject: algorithms
CLIPS>
So here's my CLIPS code
CLIPS> (deftemplate animal
(slot name)
(slot favourite-food)
(slot habitat)
(slot main-prey)
(multislot predators)
(slot distinctive-features))
CLIPS> (deffacts animal
(animal (name Sumatran-Elephant)
(favourite-food grass)
(habitat "Rainforest and tropical woodland")
(main-prey "grass, fruit, roots")
(predators Human Tiger)
(distinctive-features "Long trunk and large feet"))
(animal (name Monkey)
(favourite-food fruit)
(habitat "Tropical forests, grasslands and mountainous plains")
(main-prey "Fruit, Seeds, Insects")
(predators Birds Snakes Wildcats)
(distinctive-features "Long, agile tail and loud vocal calls"))
(animal (name Magpie)
(favourite-food fruit)
(habitat "Open woodland, grasslands and savannas")
(main-prey "Fruit, Nuts, Seeds, Insects")
(predators Foxes Cats Coyote)
(distinctive-features "Black and white markings and long wedge-shaped tail")))
CLIPS> (deftemplate find-predators(slot predators))
CLIPS> (defrule find-predators
(find-predators(predators ?predator_name))
(animal(name ?name)
(predators $?other1 ?predator_name $?other2))
=> (printout t ?predator_name " is the predator of " ?name crlf
"Other predators are " ?other1 ?other2 crlf))
CLIPS> (reset)
CLIPS> (assert(find-predators(predators Human)))
<Fact-4>
CLIPS> (run)
Human is the predator of Sumatran-Elephant
Other predators are ()(Tiger)
CLIPS> (assert(find-predators(predators Coyote)))
<Fact-5>
CLIPS> (run)
Coyote is the predator of Magpie
Other predators are (Foxes Cats)()
But the answer should be like this
Coyote is the predator of Magpie
Other predators are (Foxes) (Cats)
How do I split the facts for the multi slots above?
Need helps if anyone know the best default that can be replaced from the above code
Combine the multifield values in the variables $?other and $?other2 into a single multifield value and then use the implode$ function to convert that value into a string with spaces between the predator names.
(defrule find-predators
(find-predators (predators ?predator_name))
(animal (name ?name)
(predators $?other1 ?predator_name $?other2))
=>
(printout t ?predator_name " is the predator of " ?name crlf
"Other predators are " (implode$ (create$ ?other1 ?other2)) crlf))
is there a way to output the name of the fired rule in CLIPS?
Example:
(defrule this-is-my-rule
...
=>
(printout t "this-is-my-rule: and these are the outputs" crlf) ;;#1
)
Instead of writing manually the name of the rule in #1, I'd like to use a psecific command (if any).
Is it possible, please?
Thank
Nicola
There isn't a mechanism for programmatically determining the name of the currently executing rule, but you can use the watch debugging command to print the name of each rule as it is executed:
CLIPS> (defrule rule-1 =>)
CLIPS> (defrule rule-2 =>)
CLIPS> (defrule rule-3 =>)
CLIPS> (watch rules)
CLIPS> (run)
FIRE 1 rule-3: *
FIRE 2 rule-2: *
FIRE 3 rule-1: *
CLIPS>
(deftemplate illness
(slot sickness)
(multislot keywords))
(deffacts qestion-refrences
(illness (sickness stunted-Groth)(keywords stunted groth))
(illness (sickness pale-Yellow) (keywords pale yellow))
(illness (sickness reddish-Brown)(keywords reddish brown))
(illness (sickness stunted-Root)(keywords stunted root)))
(deffunction askquestion (?question)
(printout t ?question)
(bind ?answer (read))
(if (lexemep ?answer)
then (bind ?answer (lowcase ?answer)))
?answer)
(defrule determineSickness
(bind ?f (askquestion "whot Does the plant seem to have ? "))
(illness (keywords ?kw) (sickness ?sk))
(while (not (subsetp ?kw ?f ))
(bind ?f (askquestion "whot Does the plant seem to have ? ")))
=>
(assert ?sk))
What I am trying to do is simply ask the user what is wrong with their plant and using the keywords to identify the problem and then assert the problem. However I keep getting the following error.
Defining defrule: determineSickness
[PRNTUTIL2] Syntax Error: Check appropriate syntax for defrule.
ERROR:
(defrule MAIN::determineSickness
(bind ?f (
FALSE
CLIPS>
There's a BNF specification of valid CLIPS syntax in the CLIPS Basic Programming Guide. A relevant portion for defrules is:
<defrule-construct> ::=
(defrule <rule-name> [<comment>]
[<declaration>]
<conditional-element>*
=>
<action>*)
<action> ::= <expression>
<expression> ::= <constant> | <variable> | <function-call>
<function-call> ::= (<function-name> <expression>*)
<conditional-element> ::=
<pattern-CE> |
<assigned-pattern-CE> |
<not-CE> |
<and-CE> |
<or-CE> |
<logical-CE> |
<test-CE> |
<exists-CE> |
<forall-CE>
The when portion of the rule (the part before the =>) consists of conditions that must be matched by facts/instances in order for the rule to be applicable. You can make function calls from the conditions of the rule, but not using the syntax you've attempted. In addition, since conditions can be activated in a non-sequential order, procedural code that must be executed sequentially needs to be specified in the actions of the rule (the part after the =>).
You can make your original code syntactically correct with a few changes:
(defrule determineSickness
(illness (keywords $?kw) (sickness ?sk))
=>
(bind ?f (askquestion "whot Does the plant seem to have ? "))
(while (not (member$ ?f ?kw))
(bind ?f (askquestion "whot Does the plant seem to have ? ")))
(assert (diagnosis ?sk)))
Your rule(s) are still semantically incorrect. This is what they currently do:
For every illness, ask the user to specify one of the symptoms for that illness.
This is what they need to do:
For every symptom specified by the user, find every illness having that symptom.